<?php
/**
 * Created by PhpStorm.
 * User: Bobo
 * Date: 2017/3/24
 * Time: 12:31
 * 微信获取相关信息类
 *
 */
namespace Boo;

class WX {
    private $_base_token = ''; // 微信的基本token，通过接口获取
    private $_AppId = "wxc41cd197a1e2a6da";
    private $_AppSecret = "d621dd8727647166f3e11c2336688edd";
    
    private $_token_file = 'base_token.php';
    private $_get_type = 'base'; // 获取类型，base 只获取OpenId，userinfo 获取用户基本信息。
    
    private $_userinfo = '';
    
    
    public function __construct($conf = array()){
        $this->_url = isset($conf['url']) ? $conf['url'] : $this->_getUrl();
        $this->_get_type = 'snsapi_'.(isset($conf['get']) ? $conf['get'] : $this->_get_type);
        $this->_AppId = isset($conf['appId']) ? $conf['appId'] : $this->_AppId;
        $this->_AppSecret = isset($conf['appSecret']) ? $conf['appSecret'] : $this->_AppSecret;
        $this->_token_file = dirname(__FILE__).'/'.$this->_token_file;
        $this->_getBaseToken();
    }
    
    public function getUserInfo(){
        if($this->_userinfo === '') {
            $time = time();
            if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false ) {
                $set_cookie_flag = false;
                $tmp = trim($_COOKIE['refresh_token']);
                if (empty($tmp)) { // 防止微信多次调用
                    if (!isset($_GET['code'])) { // 并没有设置
                        $this->_goWXUrl($this->_url, $this->_get_type);
                    }
                    $code = $_GET['code'];
                    $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->_AppId.'&secret='.$this->_AppSecret.'&code='.$code.'&grant_type=authorization_code';
                    $set_cookie_flag = true;
                } else {
                    $url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token?appid='.$this->_AppId.'&grant_type=refresh_token&refresh_token=' .$_COOKIE['refresh_token'];
                }
                $rst = file_get_contents($url);
                $rst = json_decode($rst, true);
//                print_r($rst);die;
                if (isset($rst['access_token'])) {
                    if ($set_cookie_flag) {
                        setcookie('refresh_token', $rst['refresh_token'],$time + 6*86400);
                    }
                    $info = array();
                    if ($this->_get_type == 'snsapi_userinfo') {
                        $url = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$rst['access_token'].'&openid='.$rst['openid'].'&lang=zh_CN';
                        $info = json_decode(file_get_contents($url), true);
                    }
                    $url = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$this->_base_token.'&openid='.$rst['openid'] .'&lang=zh_CN';
                    $rst = json_decode(file_get_contents($url), true);
                    $this->_userinfo = array_merge($info, $rst);
                    return $this->_userinfo;
                } else { // 获取token出错
                    $this->_goWXUrl($this->_url, $this->_get_type);
                }
            }
            return NULL;
        } else {
            return $this->_userinfo;
        }
    }
    
    private function _getUrl(){
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
        return "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
    }
    
    private function _getBaseToken (){
        if(!file_exists($this->_token_file)){
            $this->_updateBaseToken();
        } else {
            $data = json_decode(trim(file_get_contents($this->_token_file)),true);
//            print_r($data);die;
            if ($data['expire_time'] < time()) { // 过期了，则更新
                $this->_updateBaseToken();
            } else {
                $this->_base_token = $data['access_token'];
            }
        }
    }
    
    /**
     * 更新BaseToken
     * @return bool
     */
    private function _updateBaseToken(){
        $rst = json_decode(file_get_contents('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$this->_AppId .'&secret='.$this->_AppSecret), true);
        if (isset($rst['access_token'])) {
            $this->_base_token = $rst['access_token'];
            // -180 三分钟空余时间
            file_put_contents($this->_token_file,json_encode(array('access_token'=>$rst['access_token'], 'expire_time'=>time() + $rst['expires_in'] - 180)));
        } else {
            return false;
        }
    }
    
    
    /**
     * snsapi_base // 获取用户OpenID即可（无感知跳转，默认授权）
     * snsapi_userinfo  // 获取用户基本信息 （需要用户授权）
     */
    private function _goWXUrl ($url,$scope='snsapi_base'){
        $time = time();
        $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->_AppId.'&redirect_uri='.urlencode($url) .'&response_type=code&scope='.$scope.'&state=1#wechat_redirect';
        cookie('refresh_token',null);
        setcookie('refresh_token','',$time-1);
        setcookie('code','',$time-1);
        header('Location:'.$url);exit();
    }

    public function getjsapi_ticket(){
        $this->_getBaseToken();
        $rst = json_decode(file_get_contents('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$this->_base_token.'&type=jsapi'), true);
        return $rst['ticket'];
    }

    public function get_user_info($openid)
    {
        $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=".$this->_base_token."&openid=".$openid."&lang=zh_CN";
        $res = $this->http_request($url);
        return json_decode($res, true);
    }

    //HTTP请求（支持HTTP/HTTPS，支持GET/POST）
    protected function http_request($url, $data = null)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)){
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }
};
